package com.knowledgegraph.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.knowledgegraph.entity.Relation;
import com.knowledgegraph.mapper.RelationMapper;
import com.knowledgegraph.service.RelationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 关系服务实现类
 */
@Slf4j
@Service
public class RelationServiceImpl extends ServiceImpl<RelationMapper, Relation> implements RelationService {

    @Autowired
    private RelationMapper relationMapper;

    /**
     * 创建关系
     */
    @Override
    @Transactional
    public boolean createRelation(Relation relation, Long creatorId) {
        try {
            log.info("开始创建关系，名称: {}, 创建者: {}", relation.getName(), creatorId);
            
            LocalDateTime now = LocalDateTime.now();
            relation.setCreateTime(now);
            relation.setUpdateTime(now);
            relation.setCreatorId(creatorId);
            relation.setDeleted(0);
            
            int result = relationMapper.insert(relation);
            if (result > 0) {
                log.info("创建关系成功，ID: {}", relation.getId());
                return true;
            }
            return false;
        } catch (Exception e) {
            log.error("创建关系失败: {}", e.getMessage(), e);
            throw new RuntimeException("创建关系失败: " + e.getMessage());
        }
    }

    /**
     * 更新关系
     */
    @Override
    @Transactional
    public boolean updateRelation(Relation relation, Long userId) {
        try {
            log.info("开始更新关系，ID: {}, 用户: {}", relation.getId(), userId);
            
            // 检查关系是否存在
            Relation existingRelation = relationMapper.selectById(relation.getId());
            if (existingRelation == null) {
                log.error("关系不存在，ID: {}", relation.getId());
                throw new RuntimeException("关系不存在");
            }
            
            relation.setUpdateTime(LocalDateTime.now());
            int result = relationMapper.updateById(relation);
            
            if (result > 0) {
                log.info("更新关系成功，ID: {}", relation.getId());
                return true;
            }
            return false;
        } catch (Exception e) {
            log.error("更新关系失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新关系失败: " + e.getMessage());
        }
    }

    /**
     * 删除关系
     */
    @Override
    @Transactional
    public boolean deleteRelation(Long relationId, Long userId) {
        try {
            log.info("开始删除关系，ID: {}, 用户: {}", relationId, userId);
            
            Relation existingRelation = relationMapper.selectById(relationId);
            if (existingRelation == null) {
                log.error("关系不存在，ID: {}", relationId);
                throw new RuntimeException("关系不存在");
            }
            
            int result = relationMapper.deleteById(relationId);
            if (result > 0) {
                log.info("删除关系成功，ID: {}", relationId);
                return true;
            }
            return false;
        } catch (Exception e) {
            log.error("删除关系失败: {}", e.getMessage(), e);
            throw new RuntimeException("删除关系失败: " + e.getMessage());
        }
    }

    /**
     * 批量删除关系
     */
    @Override
    @Transactional
    public boolean batchDeleteRelations(List<Long> relationIds, Long userId) {
        try {
            if (relationIds == null || relationIds.isEmpty()) {
                return false;
            }
            
            log.info("开始批量删除关系，数量: {}, 用户: {}", relationIds.size(), userId);
            int result = relationMapper.deleteBatchIds(relationIds);
            log.info("批量删除完成，删除数量: {}", result);
            return result > 0;
        } catch (Exception e) {
            log.error("批量删除关系失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量删除关系失败: " + e.getMessage());
        }
    }

    /**
     * 获取实体的关系
     */
    @Override
    public List<Relation> getRelationsByEntityId(Long entityId) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("entityId", entityId);
            return relationMapper.selectRelationsWithConditions(params);
        } catch (Exception e) {
            log.error("获取实体关系失败: {}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 分页查询关系
     */
    @Override
    public IPage<Relation> getRelationsWithPagination(Page<Relation> page, Map<String, Object> queryParams) {
        try {
            log.info("开始分页查询关系，页码: {}, 页大小: {}", page.getCurrent(), page.getSize());
            
            // 启动PageHelper分页
            PageHelper.startPage((int) page.getCurrent(), (int) page.getSize());
            
            // 执行查询
            List<Relation> relations = relationMapper.selectRelationsWithConditions(queryParams);
            
            // 获取分页信息
            PageInfo<Relation> pageInfo = new PageInfo<>(relations);
            
            // 转换为IPage格式
            Page<Relation> resultPage = new Page<>(page.getCurrent(), page.getSize(), pageInfo.getTotal());
            resultPage.setRecords(relations);
            
            log.info("分页查询完成，总数: {}, 当前页数据: {}", pageInfo.getTotal(), relations.size());
            return resultPage;
            
        } catch (Exception e) {
            log.error("分页查询关系失败: {}", e.getMessage(), e);
            // 返回空结果页
            Page<Relation> emptyPage = new Page<>(page.getCurrent(), page.getSize(), 0);
            emptyPage.setRecords(new ArrayList<>());
            return emptyPage;
        }
    }

    /**
     * 获取统计数据
     */
    @Override
    public Map<String, Object> getGlobalStatistics() {
        Map<String, Object> stats = new HashMap<>();
        
        try {
            log.info("开始获取全局统计数据");
            
            // 获取基础统计数据
            Map<String, Object> globalStats = relationMapper.getGlobalStatistics();
            if (globalStats != null) {
                stats.put("relationCount", globalStats.get("relationCount"));
                stats.put("entityCount", globalStats.get("entityCount"));
                stats.put("typeCount", globalStats.get("typeCount"));
            } else {
                stats.put("relationCount", 0);
                stats.put("entityCount", 0);
                stats.put("typeCount", 0);
            }
            
            // 获取类型分布统计
            List<Map<String, Object>> typeStats = relationMapper.getRelationTypeStatistics(null);
            stats.put("typeDistribution", typeStats != null ? typeStats : new ArrayList<>());
            
            // 获取活跃度趋势数据
            Map<String, Object> activityTrend = getActivityTrendData();
            stats.put("activityTrend", activityTrend);
            
            log.info("获取全局统计数据成功");
            return stats;
            
        } catch (Exception e) {
            log.error("获取全局统计数据失败: {}", e.getMessage(), e);
            // 返回空统计数据
            stats.put("relationCount", 0);
            stats.put("entityCount", 0);
            stats.put("typeCount", 0);
            stats.put("typeDistribution", new ArrayList<>());
            stats.put("activityTrend", new HashMap<>());
            return stats;
        }
    }

    /**
     * 获取用户统计数据
     */
    @Override
    public Map<String, Object> getUserStatistics(Long userId) {
        Map<String, Object> stats = new HashMap<>();
        
        try {
            log.info("开始获取用户统计数据，用户ID: {}", userId);
            
            // 获取用户的基础统计数据
            Map<String, Object> userStats = relationMapper.getUserStatistics(userId);
            if (userStats != null) {
                stats.put("relationCount", userStats.get("relationCount"));
                stats.put("entityCount", userStats.get("entityCount"));
                stats.put("typeCount", userStats.get("typeCount"));
            } else {
                stats.put("relationCount", 0);
                stats.put("entityCount", 0);
                stats.put("typeCount", 0);
            }
            
            // 获取用户的类型分布统计
            List<Map<String, Object>> typeStats = relationMapper.getUserRelationTypeStatistics(userId);
            stats.put("typeDistribution", typeStats != null ? typeStats : new ArrayList<>());
            
            // 获取用户的活跃度趋势数据
            Map<String, Object> activityTrend = getUserActivityTrendData(userId);
            stats.put("activityTrend", activityTrend);
            
            log.info("获取用户统计数据成功，用户ID: {}", userId);
            return stats;
            
        } catch (Exception e) {
            log.error("获取用户统计数据失败，用户ID: {}: {}", userId, e.getMessage(), e);
            // 返回空统计数据
            stats.put("relationCount", 0);
            stats.put("entityCount", 0);
            stats.put("typeCount", 0);
            stats.put("typeDistribution", new ArrayList<>());
            stats.put("activityTrend", new HashMap<>());
            return stats;
        }
    }

    /**
     * 从文件导入关系
     */
    @Override
    @Transactional
    public Map<String, Object> importRelationsFromFile(MultipartFile file, Long userId) throws IOException {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 这里应该实现文件解析逻辑，暂时返回成功
            result.put("success", true);
            result.put("message", "文件导入功能待实现");
            
        } catch (Exception e) {
            log.error("从文件导入关系失败: {}", e.getMessage(), e);
            result.put("success", false);
            result.put("message", "导入失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 导出关系到Excel
     */
    @Override
    public void exportRelationsToExcel(Map<String, Object> exportParams, HttpServletResponse response) throws IOException {
        try {
            log.info("开始导出关系到Excel");
            
            // 获取要导出的关系数据
            List<Relation> relations = relationMapper.selectRelationsForExport(exportParams);
            
            // 这里应该实现Excel导出逻辑，暂时只记录日志
            log.info("导出关系数据，数量: {}", relations.size());
            
        } catch (Exception e) {
            log.error("导出关系到Excel失败: {}", e.getMessage(), e);
            throw new IOException("导出失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户活跃度趋势数据
     */
    private Map<String, Object> getUserActivityTrendData(Long userId) {
        Map<String, Object> trendData = new HashMap<>();
        
        try {
            log.info("开始获取用户活跃度趋势数据，用户ID: {}", userId);
            
            // 获取周数据
            Map<String, Object> weekData = getUserWeeklyActivityData(userId);
            trendData.put("周", weekData);
            
            // 获取月数据
            Map<String, Object> monthData = getUserMonthlyActivityData(userId);
            trendData.put("月", monthData);
            
            // 获取年数据
            Map<String, Object> yearData = getUserYearlyActivityData(userId);
            trendData.put("年", yearData);
            
            log.info("获取用户活跃度趋势数据成功，用户ID: {}", userId);
            
        } catch (Exception e) {
            log.error("获取用户活跃度趋势数据失败，用户ID: {}: {}", userId, e.getMessage(), e);
        }
        
        return trendData;
    }

    /**
     * 获取用户周活跃度数据（最近7天）
     */
    private Map<String, Object> getUserWeeklyActivityData(Long userId) {
        List<String> categories = Arrays.asList("周一", "周二", "周三", "周四", "周五", "周六", "周日");
        List<Integer> barData = new ArrayList<>();
        List<Integer> lineData = new ArrayList<>();
        
        try {
            LocalDateTime endDate = LocalDateTime.now();
            LocalDateTime startDate = endDate.minusDays(6);
            
            // 获取创建统计
            List<Map<String, Object>> createStats = relationMapper.getUserRelationCreateStatsByDateRange(userId, startDate, endDate);
            Map<String, Integer> createMap = new HashMap<>();
            for (Map<String, Object> stat : createStats) {
                String date = stat.get("date").toString();
                Integer count = ((Number) stat.get("count")).intValue();
                createMap.put(date, count);
            }
            
            // 获取更新统计
            List<Map<String, Object>> updateStats = relationMapper.getUserRelationUpdateStatsByDateRange(userId, startDate, endDate);
            Map<String, Integer> updateMap = new HashMap<>();
            for (Map<String, Object> stat : updateStats) {
                String date = stat.get("date").toString();
                Integer count = ((Number) stat.get("count")).intValue();
                updateMap.put(date, count);
            }
            
            // 构建7天数据
            for (int i = 0; i < 7; i++) {
                LocalDateTime date = startDate.plusDays(i);
                String dateStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                
                barData.add(createMap.getOrDefault(dateStr, 0));
                lineData.add(updateMap.getOrDefault(dateStr, 0));
            }
            
        } catch (Exception e) {
            log.error("获取用户周活跃度数据失败，用户ID: {}: {}", userId, e.getMessage(), e);
            // 填充0值
            for (int i = 0; i < 7; i++) {
                barData.add(0);
                lineData.add(0);
            }
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("categories", categories);
        result.put("barData", barData);
        result.put("lineData", lineData);
        return result;
    }

    /**
     * 获取用户月活跃度数据（最近4周）
     */
    private Map<String, Object> getUserMonthlyActivityData(Long userId) {
        List<String> categories = Arrays.asList("第1周", "第2周", "第3周", "第4周");
        List<Integer> barData = new ArrayList<>();
        List<Integer> lineData = new ArrayList<>();
        
        try {
            LocalDateTime now = LocalDateTime.now();
            
            for (int i = 3; i >= 0; i--) {
                LocalDateTime weekStart = now.minusWeeks(i);
                LocalDateTime weekEnd = weekStart.plusWeeks(1);
                
                // 获取该周的创建和更新数据
                List<Map<String, Object>> createStats = relationMapper.getUserRelationCreateStatsByDateRange(userId, weekStart, weekEnd);
                List<Map<String, Object>> updateStats = relationMapper.getUserRelationUpdateStatsByDateRange(userId, weekStart, weekEnd);
                
                int createCount = createStats.stream().mapToInt(stat -> ((Number) stat.get("count")).intValue()).sum();
                int updateCount = updateStats.stream().mapToInt(stat -> ((Number) stat.get("count")).intValue()).sum();
                
                barData.add(createCount);
                lineData.add(updateCount);
            }
            
        } catch (Exception e) {
            log.error("获取用户月活跃度数据失败，用户ID: {}: {}", userId, e.getMessage(), e);
            // 填充0值
            for (int i = 0; i < 4; i++) {
                barData.add(0);
                lineData.add(0);
            }
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("categories", categories);
        result.put("barData", barData);
        result.put("lineData", lineData);
        return result;
    }

    /**
     * 获取用户年活跃度数据（最近4个季度）
     */
    private Map<String, Object> getUserYearlyActivityData(Long userId) {
        List<String> categories = Arrays.asList("Q1", "Q2", "Q3", "Q4");
        List<Integer> barData = new ArrayList<>();
        List<Integer> lineData = new ArrayList<>();
        
        try {
            LocalDateTime now = LocalDateTime.now();
            int currentYear = now.getYear();
            
            for (int quarter = 1; quarter <= 4; quarter++) {
                LocalDateTime quarterStart = LocalDateTime.of(currentYear, (quarter - 1) * 3 + 1, 1, 0, 0);
                LocalDateTime quarterEnd = quarterStart.plusMonths(3);
                
                // 获取该季度的创建和更新数据
                List<Map<String, Object>> createStats = relationMapper.getUserRelationCreateStatsByDateRange(userId, quarterStart, quarterEnd);
                List<Map<String, Object>> updateStats = relationMapper.getUserRelationUpdateStatsByDateRange(userId, quarterStart, quarterEnd);
                
                int createCount = createStats.stream().mapToInt(stat -> ((Number) stat.get("count")).intValue()).sum();
                int updateCount = updateStats.stream().mapToInt(stat -> ((Number) stat.get("count")).intValue()).sum();
                
                barData.add(createCount);
                lineData.add(updateCount);
            }
            
        } catch (Exception e) {
            log.error("获取用户年活跃度数据失败，用户ID: {}: {}", userId, e.getMessage(), e);
            // 填充0值
            for (int i = 0; i < 4; i++) {
                barData.add(0);
                lineData.add(0);
            }
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("categories", categories);
        result.put("barData", barData);
        result.put("lineData", lineData);
        return result;
    }

    /**
     * 获取活跃度趋势数据
     */
    private Map<String, Object> getActivityTrendData() {
        Map<String, Object> trendData = new HashMap<>();
        
        try {
            log.info("开始获取活跃度趋势数据");
            
            // 获取周数据
            Map<String, Object> weekData = getWeeklyActivityData();
            trendData.put("周", weekData);
            
            // 获取月数据
            Map<String, Object> monthData = getMonthlyActivityData();
            trendData.put("月", monthData);
            
            // 获取年数据
            Map<String, Object> yearData = getYearlyActivityData();
            trendData.put("年", yearData);
            
            log.info("获取活跃度趋势数据成功");
            
        } catch (Exception e) {
            log.error("获取活跃度趋势数据失败: {}", e.getMessage(), e);
        }
        
        return trendData;
    }

    /**
     * 获取周活跃度数据（最近7天）
     */
    private Map<String, Object> getWeeklyActivityData() {
        List<String> categories = Arrays.asList("周一", "周二", "周三", "周四", "周五", "周六", "周日");
        List<Integer> barData = new ArrayList<>();
        List<Integer> lineData = new ArrayList<>();
        
        try {
            LocalDateTime endDate = LocalDateTime.now();
            LocalDateTime startDate = endDate.minusDays(6);
            
            // 获取创建统计
            List<Map<String, Object>> createStats = relationMapper.getRelationCreateStatsByDateRange(startDate, endDate);
            Map<String, Integer> createMap = new HashMap<>();
            for (Map<String, Object> stat : createStats) {
                String date = stat.get("date").toString();
                Integer count = ((Number) stat.get("count")).intValue();
                createMap.put(date, count);
            }
            
            // 获取更新统计
            List<Map<String, Object>> updateStats = relationMapper.getRelationUpdateStatsByDateRange(startDate, endDate);
            Map<String, Integer> updateMap = new HashMap<>();
            for (Map<String, Object> stat : updateStats) {
                String date = stat.get("date").toString();
                Integer count = ((Number) stat.get("count")).intValue();
                updateMap.put(date, count);
            }
            
            // 构建7天数据
            for (int i = 0; i < 7; i++) {
                LocalDateTime date = startDate.plusDays(i);
                String dateStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                
                barData.add(createMap.getOrDefault(dateStr, 0));
                lineData.add(updateMap.getOrDefault(dateStr, 0));
            }
            
        } catch (Exception e) {
            log.error("获取周活跃度数据失败: {}", e.getMessage(), e);
            // 填充0值
            for (int i = 0; i < 7; i++) {
                barData.add(0);
                lineData.add(0);
            }
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("categories", categories);
        result.put("barData", barData);
        result.put("lineData", lineData);
        return result;
    }

    /**
     * 获取月活跃度数据（最近4周）
     */
    private Map<String, Object> getMonthlyActivityData() {
        List<String> categories = Arrays.asList("第1周", "第2周", "第3周", "第4周");
        List<Integer> barData = new ArrayList<>();
        List<Integer> lineData = new ArrayList<>();
        
        try {
            LocalDateTime now = LocalDateTime.now();
            
            for (int i = 3; i >= 0; i--) {
                LocalDateTime weekStart = now.minusWeeks(i);
                LocalDateTime weekEnd = weekStart.plusWeeks(1);
                
                // 获取该周的创建和更新数据
                List<Map<String, Object>> createStats = relationMapper.getRelationCreateStatsByDateRange(weekStart, weekEnd);
                List<Map<String, Object>> updateStats = relationMapper.getRelationUpdateStatsByDateRange(weekStart, weekEnd);
                
                int createCount = createStats.stream().mapToInt(stat -> ((Number) stat.get("count")).intValue()).sum();
                int updateCount = updateStats.stream().mapToInt(stat -> ((Number) stat.get("count")).intValue()).sum();
                
                barData.add(createCount);
                lineData.add(updateCount);
            }
            
        } catch (Exception e) {
            log.error("获取月活跃度数据失败: {}", e.getMessage(), e);
            // 填充0值
            for (int i = 0; i < 4; i++) {
                barData.add(0);
                lineData.add(0);
            }
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("categories", categories);
        result.put("barData", barData);
        result.put("lineData", lineData);
        return result;
    }

    /**
     * 获取年活跃度数据（最近4个季度）
     */
    private Map<String, Object> getYearlyActivityData() {
        List<String> categories = Arrays.asList("Q1", "Q2", "Q3", "Q4");
        List<Integer> barData = new ArrayList<>();
        List<Integer> lineData = new ArrayList<>();
        
        try {
            LocalDateTime now = LocalDateTime.now();
            int currentYear = now.getYear();
            
            for (int quarter = 1; quarter <= 4; quarter++) {
                LocalDateTime quarterStart = LocalDateTime.of(currentYear, (quarter - 1) * 3 + 1, 1, 0, 0);
                LocalDateTime quarterEnd = quarterStart.plusMonths(3);
                
                // 获取该季度的创建和更新数据
                List<Map<String, Object>> createStats = relationMapper.getRelationCreateStatsByDateRange(quarterStart, quarterEnd);
                List<Map<String, Object>> updateStats = relationMapper.getRelationUpdateStatsByDateRange(quarterStart, quarterEnd);
                
                int createCount = createStats.stream().mapToInt(stat -> ((Number) stat.get("count")).intValue()).sum();
                int updateCount = updateStats.stream().mapToInt(stat -> ((Number) stat.get("count")).intValue()).sum();
                
                barData.add(createCount);
                lineData.add(updateCount);
            }
            
        } catch (Exception e) {
            log.error("获取年活跃度数据失败: {}", e.getMessage(), e);
            // 填充0值
            for (int i = 0; i < 4; i++) {
                barData.add(0);
                lineData.add(0);
            }
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("categories", categories);
        result.put("barData", barData);
        result.put("lineData", lineData);
        return result;
    }
}